#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <linux/user.h>
#include <getopt.h>
/*
 * 	A simple program to demonstrate the power of ptrace
 */

/*
 * Method to handle attaching to an running process
 */
int handle_process_attach(int pid_to_attach)
{
	int rc, status;
	struct	user_regs_struct regs;

	status = 0;

	rc = ptrace(PTRACE_ATTACH, pid_to_attach, NULL, NULL);
	
	if (rc < 0) {
		printf("ERROR Attaching to process pid=<%d>\n", 
				pid_to_attach);
		exit(1);
	}

	printf("Waiting for process to stop\n");
	waitpid(pid_to_attach, &status, 0);
	printf("Process <%d> stopped, status <%d>\n",
		   pid_to_attach, status);

	while (1) {
		
		ptrace(PTRACE_SYSCALL, pid_to_attach, NULL, NULL);
		waitpid(pid_to_attach, &status, 0);
		ptrace(PTRACE_GETREGS, pid_to_attach, 0, &regs);
		printf("SYSCALL = %d\n", regs.orig_eax);
		ptrace(PTRACE_CONT, pid_to_attach, NULL, NULL);	
		sleep(2);

	}

	return rc;
}

/*
 * 	Method to handle launching a new process and tracing
 */
int handle_process_launch(char* filename_to_launch)
{
	int rc;
	rc = -1;

	return rc;
}
int main(int argc, char *argv[])
{
	char c;
	pid_t pid;
	char *binfile;
	 
	binfile = NULL;
	pid = -1;
	if (argc < 3) {
		printf("Not enough args\n");
		exit(1);
	}
	while ((c = getopt (argc, argv, "a:f:")) != -1) {
        switch (c) {
			case 'a':
				pid = atoi(optarg);
				break;
			case 'f':
				binfile = (char*)strdup(optarg);
				break;
			default:
				exit(1);
		}
	}

	if (pid != -1 && binfile != NULL) {
		printf("Both -a and -f cannot be given\n");
		free(binfile);
		exit(1);
	}

	if (pid >= 0) {
		handle_process_attach(pid);
	} else if (binfile != NULL) {
		handle_process_launch(binfile);
	}

	return 0;
}

